#include "chat.h"

int sockfd;
int addrlen;
struct sockaddr_in   server_addr; 

pthread_t pid;

int login_f =  -1; //标志位，用于判断用户是否已登录。

//用于接收服务器发送过来的消息
void *func(void *arg)
{
	int len;
	char buf[128]={0};
	struct protocol *msg;
	
	while(1)
	{
		if(login_f != 1) //未登录
		{
			continue;
		}	
    	fflush(stdout);		
		memset(buf,0,sizeof(buf));
		len = read(sockfd,buf,sizeof(buf));
		if(len<=0)
		{
			close(sockfd);
			return NULL;
		}
		
		msg = (struct protocol *)buf;
		//  已登录并且命令是在线
		if((msg->state == ONLINEUSER_OK)&&(msg->cmd == ONLINEUSER))
		{
			printf("用户名 %s\t",msg->name);
			continue;
		}
		
		if((msg->state == ONLINEUSER_OVER)&&(msg->cmd == ONLINEUSER))
		{
			printf("结束\n");
			continue;
		}
		
		buf[len]='\0';
		
		printf("%s\n",buf);

	}	
}

//广播
void broadcast(int fd)
{
	struct protocol msg;
	
	//命令为广播
	msg.cmd = BROADCAST; 
	printf("say:\n#");
	
	scanf("%s",msg.data);
	//将数据发送到服务端
	write(fd,&msg,sizeof(msg));
}

//私聊
void private(int fd)
{
	struct protocol msg;
	
	//命令为私聊
	msg.cmd = PRIVATE;
	
	printf("输入你想私聊的对象:\n#");	
	scanf("%s",msg.name);
	
	printf("say:\n#");	
	scanf("%s",msg.data);

	write(fd,&msg,sizeof(msg));
}

//显示在线用户
void list_online_user(int sockfd)
{
	struct protocol msg;
	//在线用户命令
	msg.cmd = ONLINEUSER;
	write(sockfd,&msg,sizeof(msg));
	getchar();
	getchar();
}

//注册
int  registe(int fd)
{
	struct protocol msg,msgback;

	msg.cmd = REGISTE;	
	printf("输入用户名\n");	
	scanf("%s",msg.name);
	printf("输入密码\n");	
	scanf("%s",msg.data);

	write(sockfd,&msg,sizeof(msg));
	read(sockfd,&msgback,sizeof(msgback));
	
	//状态码错误
	if(msgback.state != OP_OK)
	{
		printf("用户名已存在，请重试!\n");	
		getchar();
		getchar();
		return -1;
	}else{ //成功
		printf("注册成功!\n");
		getchar();
		getchar();
		return 0  ;
	}
}

//登录
int login(int fd)
{
	struct protocol msg,msgback;

	msg.cmd = LOGIN;	
	printf("输入用户名\n");	
	scanf("%s",msg.name);
	printf("输入密码\n");	
	scanf("%s",msg.data);

	write(sockfd,&msg,sizeof(msg));
	read(sockfd,&msgback,sizeof(msgback));
	//失败
	if(msgback.state != OP_OK)
	{
		printf("用户名或密码错误，请重试!\n");
		getchar();
		getchar();
		login_f = -1; 
		return NAME_PWD_NMATCH;
	}else{ //成功
		printf("登录成功!\n");
		getchar();
		getchar();
		login_f = 1;
		return OP_OK  ;
	}
}

//注销（关闭套接字连接）
int logout(int fd)
{
	close(fd);
	login_f = -1;
}

//参数对应          ip地址  端口号 
int main(int argc, char **argv)
{
	int sel;
	int ret; 
	int min_sel,max_sel;
	int portnumber;//端口号
	
	struct protocol msg;
	
	//长度小于3
	if(argc<3)
	{
		printf("cmd: %s ip portnumber\n",argv[0]);
		return -1;
	}
	//将字符串转为整数
	if((portnumber = atoi(argv[2]))<0)
	{
		fprintf(stderr,"Usage:%s hostname portnumber\a\n",argv[0]);
		exit(1);
	}

	//创建TCP socket
	sockfd = socket(PF_INET,SOCK_STREAM,0);	
	if(sockfd<0)
	{
		perror("socket() fail\n");
		return -1;
	}
	
	//协议  端口  ip地址
	server_addr.sin_family =  PF_INET;	
	server_addr.sin_port   =  htons(portnumber);
	server_addr.sin_addr.s_addr   =  inet_addr(argv[1]);  // 将点分十进制字符串转换为网络字节序的整数
	
	addrlen = sizeof(struct sockaddr_in);
	
	//连接服务器端
	connect(sockfd,(struct sockaddr* )&server_addr,addrlen);
	
	//连接上后创建线程 处理消息
	pthread_create(&pid, NULL,func, NULL);		
	
	//在while循环中显示界面
	while(1)
	{
		//getchar();
		system("clear");

		if(login_f == -1){ 		//未登录状态
			printf("├─────────────────────────────────────────────────────┤\n");
			printf("│\t\t    欢迎使用聊天系统                  │\n");
			printf("├─────────────────────────────────────────────────────┤\n");
			printf("│\t\t\t 1 注册                       │\n");
			printf("│\t\t\t 2 登录                       │\n");
		}else if(login_f == 1){ //已登录状态
			printf("├─────────────────────────────────────────────────────┤\n");
			printf("│\t\t    聊天系统主菜单                    │\n");
			printf("├─────────────────────────────────────────────────────┤\n");	
			printf("│\t\t\t 3 公聊                       │\n");
			printf("│\t\t\t 4 私聊                       │\n");
			printf("│\t\t\t 5 在线列表                   │\n");						
		}	
		printf("│\t\t\t 0 退出                       │\n");
		printf("├─────────────────────────────────────────────────────┤\n");
		fflush(stdin);
	 	printf("请输入你想选择的功能:\n");
        scanf("%d",&sel);

		if(sel == 0)
		{
			break;
		}
		if(login_f == 1)
		{
			min_sel = 3;
			max_sel = 5;
		}else if(login_f == -1){
			min_sel = 1;
			max_sel = 2;
		}
		
		if(sel<min_sel || sel > max_sel)
		{
			printf("Valid choice ,try again\n");
			sleep(1);
			continue;
		}
		switch(sel)
		{
			case 1://注册
				registe(sockfd);
				break;
			case 2://登录
				ret = login(sockfd);
				break;
			case 3://广播
				broadcast(sockfd);
				break;
			case 4://私聊
				private(sockfd);
				break;
			case 5://在线列表
				list_online_user(sockfd);
				break;
			case 0://注销
				logout(sockfd);
				break;
			default:

				break;
		}
		if(sel == 0)
		{
			exit(0);
		}
	}
	
	

}
